﻿using System;
using System.Diagnostics;
using System.Management;
using System.Threading.Tasks;

/// <summary>
/// 简化的GPU监控测试
/// </summary>
public class Program
{
    public static async Task Main(string[] args)
    {
        Console.WriteLine("=== 简化GPU监控测试 ===");

        try
        {
            // 1. 测试GPU基本信息获取
            Console.WriteLine("1. 获取GPU基本信息...");
            await TestGpuBasicInfo();

            // 2. 测试GPU使用率获取
            Console.WriteLine("\n2. 测试GPU使用率获取...");
            await TestGpuUsage();

            // 3. 测试GPU显存获取
            Console.WriteLine("\n3. 测试GPU显存获取...");
            await TestGpuMemory();

            // 4. 测试GPU温度获取
            Console.WriteLine("\n4. 测试GPU温度获取...");
            await TestGpuTemperature();

            Console.WriteLine("\n=== GPU监控测试完成 ===");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"测试过程中发生错误: {ex.Message}");
        }

        Console.WriteLine("\n按任意键退出...");
        Console.ReadKey();
    }

    private static async Task TestGpuBasicInfo()
    {
        try
        {
            using var searcher = new ManagementObjectSearcher("SELECT Name, DriverVersion, AdapterRAM FROM Win32_VideoController");
            foreach (ManagementObject obj in searcher.Get())
            {
                var name = obj["Name"]?.ToString();
                if (!string.IsNullOrEmpty(name) && !name.Contains("Microsoft Basic"))
                {
                    Console.WriteLine($"GPU名称: {name}");
                    Console.WriteLine($"驱动版本: {obj["DriverVersion"]?.ToString() ?? "未知"}");

                    if (obj["AdapterRAM"] != null && uint.TryParse(obj["AdapterRAM"].ToString(), out uint adapterRAM))
                    {
                        var totalMemoryGB = adapterRAM / 1024.0 / 1024.0 / 1024.0;
                        Console.WriteLine($"显存总量: {totalMemoryGB:F1}GB");
                    }
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"获取GPU基本信息失败: {ex.Message}");
        }
    }

    private static async Task TestGpuUsage()
    {
        try
        {
            // 方法1：尝试使用性能计数器
            try
            {
                using var gpuCounter = new PerformanceCounter("GPU Engine", "Utilization Percentage", "_Total");
                var usage = gpuCounter.NextValue();
                Console.WriteLine($"GPU使用率 (性能计数器): {usage:F1}%");
                return;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"性能计数器方法失败: {ex.Message}");
            }

            // 方法2：尝试nvidia-smi
            var nvidiaUsage = await GetNvidiaGpuUsage();
            if (nvidiaUsage.HasValue)
            {
                Console.WriteLine($"GPU使用率 (nvidia-smi): {nvidiaUsage.Value:F1}%");
            }
            else
            {
                Console.WriteLine("无法获取GPU使用率");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"获取GPU使用率失败: {ex.Message}");
        }
    }

    private static async Task TestGpuMemory()
    {
        try
        {
            var nvidiaMemory = await GetNvidiaGpuMemory();
            if (nvidiaMemory.HasValue)
            {
                Console.WriteLine($"GPU显存已用 (nvidia-smi): {nvidiaMemory.Value / 1024.0:F1}GB");
            }
            else
            {
                Console.WriteLine("无法获取GPU显存使用情况");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"获取GPU显存失败: {ex.Message}");
        }
    }

    private static async Task TestGpuTemperature()
    {
        try
        {
            var nvidiaTemp = await GetNvidiaGpuTemperature();
            if (nvidiaTemp.HasValue)
            {
                Console.WriteLine($"GPU温度 (nvidia-smi): {nvidiaTemp.Value:F1}°C");
            }
            else
            {
                Console.WriteLine("无法获取GPU温度");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"获取GPU温度失败: {ex.Message}");
        }
    }

    private static async Task<double?> GetNvidiaGpuUsage()
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=utilization.gpu --format=csv,noheader,nounits",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };

            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && double.TryParse(output.Trim(), out double usage))
                {
                    return usage;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"nvidia-smi使用率查询失败: {ex.Message}");
        }

        return null;
    }

    private static async Task<long?> GetNvidiaGpuMemory()
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=memory.used --format=csv,noheader,nounits",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };

            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && long.TryParse(output.Trim(), out long memoryUsed))
                {
                    return memoryUsed;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"nvidia-smi显存查询失败: {ex.Message}");
        }

        return null;
    }

    private static async Task<double?> GetNvidiaGpuTemperature()
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=temperature.gpu --format=csv,noheader,nounits",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };

            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && double.TryParse(output.Trim(), out double temperature))
                {
                    return temperature;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"nvidia-smi温度查询失败: {ex.Message}");
        }

        return null;
    }
}
